/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * TrainingBook
 * Copyright (C) Arnaud Duval 2010 <arnaud.duval@gmail.com>
 * 
 * TrainingBook is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * TrainingBook is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _O_S_M_MAP_AREA_HPP_
#define _O_S_M_MAP_AREA_HPP_

#include <gtkmm.h>
#include <list>
#include "osm-map-bounding-box.hpp"
#include "osm-map-tile-cache.hpp"
#include <Track.hpp>

///@class OsmMapArea
///@brief Define a drawing for openstreetmap map
class OsmMapArea : public Gtk::DrawingArea
{
    public:
        ///@brief Default constructor
        OsmMapArea();
        ///@brief Constructor specifying the tiles repository location
        OsmMapArea(std::string, std::string);
        ///@brief Destructor
        ~OsmMapArea();
        ///@brief Set the bounding box
        void SetBoundingBox(double, double, double, double);
        ///@brief Increase the zoom level
        void IncreaseZoomLevel(bool redraw = true);
        ///@brief Decrease the zoom level
        void DecreaseZoomLevel(bool redraw = true);
        ///@brief Set the zoom level
        void SetZoomLevel(unsigned int, bool redraw = true);
        ///@brief Get the zoom level
        unsigned int GetZoomLevel();
        ///@brief Add a track to plot
        void AddTrack(Track);
        ///@brief Translate the map
        void Move(int, int, bool redraw = true);
        ///@brief Clear the tracks
        void ClearTracks();
        ///@brief Set the tiles repository
        void SetTilesRepository(std::string);
        ///@brief Set the tiles cache
        void SetTilesCache(std::string);
        ///@brief Set the status bar on wich informations about the map area should be displayed
        void SetStatusBar(Gtk::Statusbar*);

    protected:
        ///@brief Override default signal handler for expose
        virtual bool on_expose_event(GdkEventExpose* event);
        ///@brief Override default signal hander for button press
        virtual bool on_button_press_event(GdkEventButton* event);
        ///@brief Override default signal hander for button release
        virtual bool on_button_release_event(GdkEventButton* event);
        ///@brief Override default signal handler for mouse motion
        virtual bool on_motion_notify_event(GdkEventMotion* event);
        ///@brief Refresh the map
        void RefreshMap(Glib::RefPtr<Gdk::Window>);
        ///@brief Refresh the tracks
        void RefreshTracks(Glib::RefPtr<Gdk::Window>);
        ///@brief Plot a track on the map
        void PlotTrack(Glib::RefPtr<Gdk::Window>, std::list<double>, std::list<double>);
        ///@brief Convert longitude and latitude values list in Mercator coordinates
        void DegreesToMercator(std::list<double>&, std::list<double>&);
        ///@brief Convert Mercator coordinates into latitude and longitude
        void MercatorToDegrees(double&, double&);

    private:
        ///@brief Current zoom level
        unsigned int zoomLevel;
        ///@brief Bounding Box;
        OsmMapBoundingBox bbox;
        ///@brief Tile cache
        OsmMapTileCache tCache;
        ///@brief Plotted tracks
        std::list<Track> tracks;
        ///@brief List of plots : X values
        std::list<std::list<double> > plotsX;
        ///@brief List of plots : Y values
        std::list<std::list<double> > plotsY;
        ///@brief Mouse x position on button press
        int mouse_x_on_press;
        ///@brief Mouse y position on button press
        int mouse_y_on_press;
        ///@brief Pointer to a status bar
        Gtk::Statusbar *statusBar;
        ///@brief Boolean indicating if we are drawing a track
        bool isDrawing;
        ///@brief The drawn tracks
        Track drawnTrack;
        ///@brief Current drawing : X values
        std::list<double> drawX;
        ///@brief Current drawing : Y values
        std::list<double> drawY;

};

#endif  // _O_S_M_MAP_AREA_HPP_ //